package controller;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.sql.ResultSet;
import java.sql.SQLException;

import view.MainView;
import view.UtenteView;

import com.sun.rowset.CachedRowSetImpl;

public class ControllerClienteImpl implements ControllerCliente {
	protected MainView main;
	protected UtenteView uv;
	private ObjectInputStream input;
	private ObjectOutputStream output;
	private Socket socket;
	private InetAddress addr = InetAddress.getByName(null);
	private int PORT = 1235;

	public ControllerClienteImpl(MainView m) throws SQLException, IOException {
		main = m;
		uv = main.getUtenteView();

	}

	@Override
	public ResultSet visualizzaStorico(String order) {

		ResultSet ris = null;
		try {
			output.writeObject("mioStorico_" + order + "_"
					+ main.getIdAccesso());
			output.flush();
			CachedRowSetImpl crs = (CachedRowSetImpl) input.readObject();
			ris = crs.getOriginal();
		} catch (IOException e) {
			main.erroreComunicazioneUtente(socket.isConnected());
		} catch (ClassNotFoundException e) {
			main.erroreComunicazioneUtente(socket.isConnected());
		} catch (SQLException ex) {
			main.erroreComunicazioneUtente(socket.isConnected());
		}
		return ris;

	}

	@Override
	public ResultSet cercaLibro(String[] parametri) {
		ResultSet ris = null;
		uv = main.getUtenteView();
		try {

			for (int i = 0; i < 4; i++)
				if (parametri[i].length() < 2)
					parametri[i] = "null";
			if (parametri[0] != "null" || parametri[1] != "null"
					|| parametri[2] != "null" || parametri[3] != "null") {
			} else {

				uv.inserireAlcuniParametri();
				return null;
			}
			output.writeObject("cercaLibro_" + parametri[0] + "_"
					+ parametri[1] + "_" + parametri[2] + "_" + parametri[3]);
			output.flush();
			CachedRowSetImpl crs = (CachedRowSetImpl) input.readObject();
			ris = crs.getOriginal();
		} catch (SQLException e) {
			main.erroreComunicazioneUtente(true);
		} catch (IOException e) {
			// uv.togliCercaLibro();
			main.erroreComunicazioneUtente(false);
		} catch (ClassNotFoundException e) {
			// uv.togliCercaLibro();
			main.erroreComunicazioneUtente(false);
		}
		return ris;
	}

	@Override
	public void accedi(int idCliente, String password) {
		try {
			uv = main.getUtenteView();
			socket = new Socket(addr, PORT);
			output = new ObjectOutputStream(socket.getOutputStream());
			input = new ObjectInputStream(socket.getInputStream());
			output.writeObject("getPassword2_" + idCliente);
			output.flush();
			String ris = (String) input.readObject();
			if (ris.equals(password)) {
				main.accessoRiuscitoCliente(idCliente);
			} else {
				if (ris.equals("null")) {
					main.erroreComunicazioneUtente(socket.isConnected());
				} else {
					main.accessoNegato();
					socket.close();
				}
			}

		} catch (IOException e) {
			main.erroreComunicazioneUtente(false);
		} catch (ClassNotFoundException e) {
			main.erroreComunicazioneUtente(false);
		}
	}

	@Override
	public void cambiaMail(String vecchiaMail, String nuovaMail) {
		uv = main.getUtenteView();
		String regex = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
		try {
			if (vecchiaMail.equals(nuovaMail) && nuovaMail.matches(regex)) {
				output.writeObject("setMail_" + nuovaMail + "_"
						+ main.getIdAccesso());
				output.flush();
				uv.cambioMailEffettuato();
			} else
				throw new IllegalArgumentException();

		} catch (IllegalArgumentException ia) {
			uv.mailIncorretta();
		} catch (IOException e) {
			uv.togliCambiaMail();
			main.erroreComunicazioneUtente(false);
		}
	}

	@Override
	public void aggiornaPrestito(long isbn) {
		uv = main.getUtenteView();
		try {
			output.writeObject("getCredenziali_" + main.getIdAccesso());
			output.flush();
			ResultSet res = null;
			output.writeObject("possoProlungarePrestito_" + isbn + "_"
					+ main.getIdAccesso());
			output.flush();
			CachedRowSetImpl crs = (CachedRowSetImpl) input.readObject();
			res = crs.getOriginal();
			res.next();
			int numeroGiorni = res.getInt("numeroGiorni");
			if (numeroGiorni > 31) {
				uv.limitiGiorniRaggiunti(numeroGiorni);
				return;
			}
			int idCliente = main.getIdAccesso();
			output.writeObject("aggiornaPrestito_" + isbn + "_" + idCliente);
			output.flush();
			output.writeObject("getDataStimata_" + isbn + "_" + idCliente);
			output.flush();
			String finePrestitoString = (String) input.readObject();
			output.writeObject("segnalaConfermaRinnovo_" + isbn + "_"
					+ finePrestitoString);
			output.flush();
			uv.rinnovoPrestitoRiuscito();
		} catch (SQLException e) {
			uv.nonPosssoAggiornarePrestito();
		} catch (IOException e) {
			main.erroreComunicazioneUtente(false);
		} catch (ClassNotFoundException e) {
			main.erroreComunicazioneUtente(false);
		} catch (ArrayIndexOutOfBoundsException ex) {
			uv.nonPosssoAggiornarePrestito();
		}
	}

	public ResultSet getConsigliati(int idCliente) {
		String generePreferitoDalCliente = null;
		try {
			output.writeObject("getGenerePreferito_" + idCliente);
			output.flush();
			generePreferitoDalCliente = (String) input.readObject();
			output.writeObject("consigliati_" + generePreferitoDalCliente);
			output.flush();
			ResultSet res = null;
			CachedRowSetImpl crs = (CachedRowSetImpl) input.readObject();
			res = crs.getOriginal();
			return res;
		} catch (SQLException s) {
			generePreferitoDalCliente = "genere";
			try {
				output.writeObject("consigliati_" + generePreferitoDalCliente);
				output.flush();
				ResultSet res = null;
				CachedRowSetImpl crs = (CachedRowSetImpl) input.readObject();
				res = crs.getOriginal();
				return res;
			} catch (SQLException e) {
				return null;
			} catch (IOException e) {
				main.erroreComunicazioneUtente(socket.isConnected());
			} catch (ClassNotFoundException e) {
				main.erroreComunicazioneUtente(socket.isConnected());
			}
		} catch (IOException e) {
			main.erroreComunicazioneUtente(socket.isConnected());
		} catch (ClassNotFoundException e) {
			main.erroreComunicazioneUtente(socket.isConnected());
		}
		return null;

	}

	public void chiudiConnessione() {
		try {
			socket.close();
		} catch (IOException e) {
		}
	}
}
